
import java.io.IOException;
import java.util.Iterator;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;


public class MaxTemp 
{
    private class MaxTempMapper extends MapReduceBase
                   implements Mapper<LongWritable, Text, Text, IntWritable> 
    {
        private static final int MISSING = 9999;

        @Override
        public void map(LongWritable key, Text value, 
                    OutputCollector<Text, IntWritable> output,
                    Reporter reporter) 
            throws IOException
        {
            String line = value.toString();
            String year = line.substring(0, 4);

            int airTemperature = Integer.parseInt(line.substring(7,12));

            String quality = line.substring(12, 13);
            if (airTemperature != MISSING && quality.matches("[01459]")) {
                output.collect(new Text(year), new IntWritable(airTemperature));
            }
        }
    }

    private class MaxTempReducer extends MapReduceBase
            implements Reducer<Text, IntWritable, Text, IntWritable> 
    {
        @Override
        public void reduce(Text key, Iterator<IntWritable> values,
                       OutputCollector<Text, IntWritable> output,
                       Reporter reporter)
            throws IOException
        {
            int maxValue = Integer.MIN_VALUE;
            while (values.hasNext()) {
                maxValue = Math.max(maxValue, values.next().get());
            }

            output.collect(key, new IntWritable(maxValue));
        }
    }

    public static void main(String[] args) throws IOException
    {
        if (args.length != 2) {
            System.err.println("Error!");
            System.exit(1);
        }
        JobConf conf = new JobConf(MaxTemp.class);
        conf.setJobName("Max Temperature");
        conf.addResource(new Path("/etc/hadoop/conf/core-site.xml"));
        conf.addResource(new Path("/etc/hadoop/conf/hdfs-site.xml"));

        FileInputFormat.addInputPath(conf, new Path(args[0]));
        FileOutputFormat.setOutputPath(conf, new Path(args[1]));

        conf.setMapperClass(MaxTempMapper.class);
        conf.setReducerClass(MaxTempReducer.class);
        conf.setOutputKeyClass(Text.class);
        conf.setOutputValueClass(IntWritable.class);

        JobClient.runJob(conf);
    }
}

